// 存储工具类，用于跨页面状态同步

export class StorageManager {
  private static instance: StorageManager
  private listeners: Map<string, Set<(value: any) => void>> = new Map()

  private constructor() {
    // 监听storage事件，实现跨页面同步
    window.addEventListener('storage', this.handleStorageChange.bind(this))
  }

  static getInstance(): StorageManager {
    if (!StorageManager.instance) {
      StorageManager.instance = new StorageManager()
    }
    return StorageManager.instance
  }

  // 设置存储值并通知监听器
  setItem(key: string, value: any): void {
    const stringValue = JSON.stringify(value)
    localStorage.setItem(key, stringValue)
    
    // 通知当前页面的监听器
    this.notifyListeners(key, value)
  }

  // 获取存储值
  getItem<T>(key: string, defaultValue?: T): T | null {
    try {
      const item = localStorage.getItem(key)
      if (item === null) {
        return defaultValue || null
      }
      return JSON.parse(item)
    } catch (error) {
      console.error(`解析存储值失败 (${key}):`, error)
      return defaultValue || null
    }
  }

  // 删除存储值
  removeItem(key: string): void {
    localStorage.removeItem(key)
    this.notifyListeners(key, null)
  }

  // 清空存储
  clear(): void {
    localStorage.clear()
    // 通知所有监听器
    this.listeners.forEach((listeners, key) => {
      this.notifyListeners(key, null)
    })
  }

  // 添加监听器
  addListener(key: string, callback: (value: any) => void): void {
    if (!this.listeners.has(key)) {
      this.listeners.set(key, new Set())
    }
    this.listeners.get(key)!.add(callback)
  }

  // 移除监听器
  removeListener(key: string, callback: (value: any) => void): void {
    const listeners = this.listeners.get(key)
    if (listeners) {
      listeners.delete(callback)
      if (listeners.size === 0) {
        this.listeners.delete(key)
      }
    }
  }

  // 处理storage变化事件（跨页面同步）
  private handleStorageChange(event: StorageEvent): void {
    // 只处理我们已经注册了监听器的键，忽略其他应用/扩展创建的键
    if (!event.key || !this.listeners.has(event.key)) {
      return
    }

    if (event.newValue !== null) {
      try {
        const value = JSON.parse(event.newValue)
        this.notifyListeners(event.key, value)
      } catch (error) {
        // 只对我们关心的键输出错误，其他键的解析失败可以忽略
        // 这可能是其他应用或浏览器扩展创建的非JSON格式数据
        console.warn(`解析storage事件值失败 (${event.key}):`, error)
      }
    } else {
      // 键被删除
      this.notifyListeners(event.key, null)
    }
  }

  // 通知监听器
  private notifyListeners(key: string, value: any): void {
    const listeners = this.listeners.get(key)
    if (listeners) {
      listeners.forEach(callback => {
        try {
          callback(value)
        } catch (error) {
          console.error(`存储监听器回调执行失败 (${key}):`, error)
        }
      })
    }
  }
}

// 导出单例实例
export const storageManager = StorageManager.getInstance()

// 便捷方法
export const setStorageItem = (key: string, value: any) => storageManager.setItem(key, value)
export const getStorageItem = <T>(key: string, defaultValue?: T) => storageManager.getItem<T>(key, defaultValue)
export const removeStorageItem = (key: string) => storageManager.removeItem(key)
export const addStorageListener = (key: string, callback: (value: any) => void) => storageManager.addListener(key, callback)
export const removeStorageListener = (key: string, callback: (value: any) => void) => storageManager.removeListener(key, callback)